﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Freeform;


namespace Space_in_Shaders
{
    public class SpaceShip : SpaceObject
    {
        public NMotion NMot { get; set; }
        public Single NextPuff { get; set; }
        public Single PuffOffset { get; set; }
        public Single PuffSpacing { get; set; }
        public Single NextLaser { get; set; }
        public Single LaserSpacing { get; set; }
        public Single NextMissile { get; set; }
        public Single MissileSpacing { get; set; }
        public Boolean IsThrusting { get; set; }
        public Boolean IsFiringLaser { get; set; }
        public Boolean IsFiringMissile { get; set; }
        public Single LaserOffset { get; set; }
        public Single LaserSpeed { get; set; }
        public Single MissileSpeed { get; set; }
        public Int32 Points { get; set; }


        public SpaceShip(SpaceWorld w)
            : base(w)
        {
            SpatialProperties.Size = new Vector2(16, 16);
            NMot = new NMotion(SpatialProperties);
            NMot.ForceResistance = 0.992f;
            
            PuffSpacing = 300;
            PuffOffset = -7;
            NextPuff = PuffSpacing;
            LaserSpacing = 100;
            LaserSpeed = 320f;
            LaserOffset = 12;
            NextLaser = LaserSpacing;
            MissileSpacing = 600;
            MissileSpeed = 50f;
            NextMissile = MissileSpacing;
            Damage = 10;

            // Setup collision properties for the spaceship.
            CollisionProperties.CollisionType = CollisionType.Active;
            Radial = new RadialCollision(this, 10);
        }

        public override void Update(GameTime time)
        {
            base.Update(time);

            // Create smoke trails.
            if (NextPuff > 0)
                NextPuff -= time.ElapsedGameTime.Milliseconds;

            if (IsThrusting && NextPuff < 0)
            {
                NextPuff = PuffSpacing;
                Vector2 Loc = SpatialProperties.Position + Util.Vec2InDir(SpatialProperties.Direction) * PuffOffset;
                new SmokePuff(SpaceWorld,  Loc, NMot.Velocity, 3);
                new Flame(SpaceWorld, Loc, NMot.Velocity, 3);
            }


            // Create lasers and missiles.
            if (NextLaser > 0)
                NextLaser -= time.ElapsedGameTime.Milliseconds;
            if (NextMissile > 0)
                NextMissile -= time.ElapsedGameTime.Milliseconds;

            if (IsFiringLaser && NextLaser < 0)
            {
                NextLaser = LaserSpacing;
                new Laser(SpaceWorld, SpatialProperties.Position + Util.Vec2InDir(SpatialProperties.Direction) * LaserOffset, SpatialProperties.Direction, LaserSpeed);
                SpaceWorld.PlaySound(SpaceWorld.LaserEffect[Game.Random.Int32(0, SpaceWorld.LaserEffect.Length)], SpatialProperties.Position, 0.45f);
            }

            if (IsFiringMissile && NextMissile < 0)
            {
                NextMissile = MissileSpacing;
                
                // Checks to see who owns the Missile and sets who it should Target.
                if (GetType() == typeof(PlayerShip))
                {
                    // Find the closest target to the crosshair;
                    // CompareValue stores the closest comparison to the crosshair. Is set to a large number to allow the first comparison to always be smaller.
                    // SaveIteration stores the compared Entity for creating a Missile after the loop is complete.
                    Single CompareValue = 100000000f;
                    Entity SaveIteration = null;

                    foreach (Entity Ent in SpaceWorld.ComponentList.ActiveColliders)
                        if (Ent != this && (Ent.GetType() == typeof(EnemyShip) || Ent.GetType() == typeof(EnemyBomber)))
                        {
                            Single Compare = (Ent.SpatialProperties.Position - SpaceWorld.XHair.SpatialProperties.Position).LengthSquared();
                            if (Compare < CompareValue)
                            {
                                CompareValue = Compare;
                                SaveIteration = Ent;
                            }
                        }

                    // Create missile going for the target discovered during the loop above.
                    if (SaveIteration != null)
                    {
                        new Missile(SaveIteration as SpaceShip, this, SpatialProperties.Position + Util.Vec2InDir(SpatialProperties.Direction) * LaserOffset, SpatialProperties.Direction, NMot.Velocity.Length());
                        SpaceWorld.PlaySound(SpaceWorld.MissileEffect[Game.Random.Int32(0, SpaceWorld.MissileEffect.Length)], SpatialProperties.Position, 1f);
                    }
                }
                else if (!SpaceWorld.Player.IsDestroyed)
                {
                    // Create missile going for the player.
                    new Missile(SpaceWorld.Player, this, SpatialProperties.Position + Util.Vec2InDir(SpatialProperties.Direction) * LaserOffset, SpatialProperties.Direction, NMot.Velocity.Length());
                    SpaceWorld.PlaySound(SpaceWorld.MissileEffect[Game.Random.Int32(0, SpaceWorld.MissileEffect.Length)], SpatialProperties.Position, 1f);
                }
            }
        }

        public override void OnDestroy()
        {
            base.OnDestroy();

            SpaceWorld.PlaySound(SpaceWorld.ExplosionEffect[Game.Random.Int32(0, SpaceWorld.ExplosionEffect.Length)], SpatialProperties.Position, 1f);

            if (Points > 0 && !SpaceWorld.Player.IsDestroyed)
            {
                SpaceWorld.Score += Points;
                new FloatingText(SpaceWorld, "+" + Points, SpatialProperties.Position, new Vector2(0, -75), 1000);
                SpaceWorld.Overlay.ScoreDisplay.Actor.ColourOverlay = Color.Green;
            }
        }
    }
}
